package level

import (
	"bytes"
	"encoding/gob"
	"errors"
	"reflect"

	"github.com/syndtr/goleveldb/leveldb"
	"google.golang.org/protobuf/proto"
)

// Get 读取数据.
func (p *Service) Get(key []byte, obj interface{}) bool {
	data, err := p.DB.Get(key, nil)
	if errors.Is(leveldb.ErrNotFound, err) {
		return false
	}

	if err != nil {
		panic(err)
	}

	if err := Bytes2Interface(data, obj); err != nil {
		panic(err)
	}

	return true
}

// Bytes2Interface 字节码转换到接口.
func Bytes2Interface(data []byte, obj interface{}) error {
	value := reflect.ValueOf(obj)
	if value.Kind() != reflect.Ptr {
		return ErrNotPtr
	}
	// protobuf
	if m, ok := value.Interface().(proto.Message); ok {
		return proto.Unmarshal(data, m)
	}
	// 加载器
	if m, ok := value.Interface().(Loader); ok {
		return m.Load(data)
	}
	// []byte
	e := reflect.TypeOf(obj).Elem()
	if e.Kind() == reflect.Slice && e.Elem().Kind() == reflect.Uint8 {
		value.Elem().Set(reflect.ValueOf(data))

		return nil
	}
	// god
	decoder := gob.NewDecoder(bytes.NewBuffer(data))

	return decoder.Decode(obj)
}
